import time

from flask import jsonify
from pyModbusTCP.client import ModbusClient

# import getLongMenResult

# 设置Modbus TCP客户端
c = ModbusClient(host="192.168.1.16", port=502)  # 替换成你的设备IP地址和端口号

# 打开连接
if not c.is_open:
    if not c.open():
        print("无法连接到Modbus设备,龙门")
        exit(1)

#机械必类
class RoboticArm:
    def __init__(self, work):
        self.work = work

#仓库类
class wareItem:
    def __init__(self, x1,x2,y1,y2, status, name):
        self.x1 = x1
        self.x2 = x2
        self.y1 = y1
        self.y2 = y2
        self.status = status
        self.name = name

class OKItem:
    def __init__(self, x1, x2, y1, y2, status, name):
        self.x1 = x1
        self.x2 = x2
        self.y1 = y1
        self.y2 = y2
        self.status = status
        self.name = name

#NG库类，三个属性：x轴，y轴，状态
class NGItem:
    def __init__(self, x1, x2, y1, y2, status, name):
        self.x1 = x1
        self.x2 = x2
        self.y1 = y1
        self.y2 = y2
        self.status = status
        self.name = name

#获取原料
def getMaterial(user_input):
    global wareHouse  # 声明 wareHouse 为全局变量

    for item in wareHouse:#wareHouse
        if item.status == "have":#if wareHouse:#len(wareHouse) >= 1
            addr2 = 0x0002  # 寄存器地址
            value_to_write2 = item.x1  # 0x4409
            result2 = c.write_single_register(addr2, value_to_write2)

            addr3 = 0x0003  # 寄存器地址
            value_to_write3 = item.x2  # 0x8000
            result3 = c.write_single_register(addr3, value_to_write3)

            addr6 = 0x0006  # 寄存器地址
            value_to_write6 = item.y1  # 0x433e
            result6 = c.write_single_register(addr6, value_to_write6)

            addr7 = 0x0007  # 寄存器地址
            value_to_write7 = item.y2  # 0x0000
            result7 = c.write_single_register(addr7, value_to_write7)

            addr4 = 0x0004  # 寄存器地址
            value_to_write4 = 0x0000  # 0x4409#0x43ca,0x8000,0x42be,0x0000
            result4 = c.write_single_register(addr4, value_to_write4)

            addr5 = 0x0005  # 寄存器地址
            value_to_write5 = 0x0000  # 0x8000
            result5 = c.write_single_register(addr5, value_to_write5)

            addr8 = 0x0008  # 寄存器地址
            value_to_write8 = 0x0000  # 0x433e
            result8 = c.write_single_register(addr8, value_to_write8)

            addr9 = 0x0009  # 寄存器地址
            value_to_write9 = 0x0000  # 0x0000
            result9 = c.write_single_register(addr9, value_to_write9)

            # 写入寄存器值1到地址0x0000      0放料或取料的动作命令  1取料 2放料
            addr = 0x0000  # 寄存器地址
            value_to_write = 1
            result = c.write_single_register(addr, value_to_write)

            item.status="Not"
            #removed_material = item.pop(0).name  # 移除仓库第一个原料位置
            removed_masterial = item.name
            robotic_arm.work = "Working"
            return f"取料完成，已取得原料：{removed_masterial}"
            #break
        #else:
            #return "仓库中没有原料"
            #break
    return "仓库中没有原料"
#放置成品
def putMaterial(user_input):
    global NGHouse
    global OKHouse

    if user_input == "放料OK":
        for item in OKHouse:
            if item.status == "empty":

                addr4 = 0x0004  # 寄存器地址
                value_to_write4 = 0x0000  # 0x4409#0x43ca,0x8000,0x42be,0x0000
                result4 = c.write_single_register(addr4, value_to_write4)

                addr5 = 0x0005  # 寄存器地址
                value_to_write5 = 0x0000  # 0x8000
                result5 = c.write_single_register(addr5, value_to_write5)

                addr8 = 0x0008  # 寄存器地址
                value_to_write8 = 0x0000  # 0x433e
                result8 = c.write_single_register(addr8, value_to_write8)

                addr9 = 0x0009  # 寄存器地址
                value_to_write9 = 0x0000  # 0x0000
                result9 = c.write_single_register(addr9, value_to_write9)

                addr2 = 0x0002  # 寄存器地址
                value_to_write2 = item.x1  # 0x4409
                result2 = c.write_single_register(addr2, value_to_write2)

                addr3 = 0x0003  # 寄存器地址
                value_to_write3 = item.x2  # 0x8000
                result3 = c.write_single_register(addr3, value_to_write3)

                addr6 = 0x0006  # 寄存器地址
                value_to_write6 = item.y1  # 0x433e
                result6 = c.write_single_register(addr6, value_to_write6)

                addr7 = 0x0007  # 寄存器地址
                value_to_write7 = item.y2  # 0x0000
                result7 = c.write_single_register(addr7, value_to_write7)

                # 写入寄存器值1到地址0x0000      0放料或取料的动作命令  1取料 2放料
                addr = 0x0000  # 寄存器地址
                value_to_write = 2
                result = c.write_single_register(addr, value_to_write)

                item.status="FullOK"
                #removed_material = OKHouse.pop(0).name  # 移除仓库第一个原料位置
                robotic_arm.work = "Working"
                return f"放料完成，已放置到：{item.name}"
            #else:
        for item in NGHouse:
            if item.status =="empty" :
                addr4 = 0x0004  # 寄存器地址
                value_to_write4 = 0x0000  # 0x4409#0x43ca,0x8000,0x42be,0x0000
                result4 = c.write_single_register(addr4, value_to_write4)

                addr5 = 0x0005  # 寄存器地址
                value_to_write5 = 0x0000  # 0x8000
                result5 = c.write_single_register(addr5, value_to_write5)

                addr8 = 0x0008  # 寄存器地址
                value_to_write8 = 0x0000  # 0x433e
                result8 = c.write_single_register(addr8, value_to_write8)

                addr9 = 0x0009  # 寄存器地址
                value_to_write9 = 0x0000  # 0x0000
                result9 = c.write_single_register(addr9, value_to_write9)

                addr2 = 0x0002  # 寄存器地址
                value_to_write2 = item.x1  # 0x4409
                result2 = c.write_single_register(addr2, value_to_write2)

                addr3 = 0x0003  # 寄存器地址
                value_to_write3 = item.x2  # 0x8000
                result3 = c.write_single_register(addr3, value_to_write3)

                addr6 = 0x0006  # 寄存器地址
                value_to_write6 = item.y1  # 0x433e
                result6 = c.write_single_register(addr6, value_to_write6)

                addr7 = 0x0007  # 寄存器地址
                value_to_write7 = item.y2  # 0x0000
                result7 = c.write_single_register(addr7, value_to_write7)

                # 写入寄存器值1到地址0x0000      0放料或取料的动作命令  1取料 2放料
                addr = 0x0000  # 寄存器地址
                value_to_write = 2
                result = c.write_single_register(addr, value_to_write)

                item.status="FullOK"
                #removed_material = NGHouse.pop(0)  # 移除仓库第一个原料位置
                robotic_arm.work = "Working"
                return f"OK库已满，放料完成，已暂时放置到：{item.name}"
            #else:
        return "成品库已满"

    elif user_input == "放料NG":
        for item in NGHouse:
            if item.status=="empty":

                addr4 = 0x0004  # 寄存器地址
                value_to_write4 = 0x0000  # 0x4409#0x43ca,0x8000,0x42be,0x0000
                result4 = c.write_single_register(addr4, value_to_write4)

                addr5 = 0x0005  # 寄存器地址
                value_to_write5 = 0x0000  # 0x8000
                result5 = c.write_single_register(addr5, value_to_write5)

                addr8 = 0x0008  # 寄存器地址
                value_to_write8 = 0x0000  # 0x433e
                result8 = c.write_single_register(addr8, value_to_write8)

                addr9 = 0x0009  # 寄存器地址
                value_to_write9 = 0x0000  # 0x0000
                result9 = c.write_single_register(addr9, value_to_write9)

                addr2 = 0x0002  # 寄存器地址
                value_to_write2 = item.x1  # 0x4409
                result2 = c.write_single_register(addr2, value_to_write2)

                addr3 = 0x0003  # 寄存器地址
                value_to_write3 = item.x2  # 0x8000
                result3 = c.write_single_register(addr3, value_to_write3)

                addr6 = 0x0006  # 寄存器地址
                value_to_write6 = item.y1  # 0x433e
                result6 = c.write_single_register(addr6, value_to_write6)

                addr7 = 0x0007  # 寄存器地址
                value_to_write7 = item.y2  # 0x0000
                result7 = c.write_single_register(addr7, value_to_write7)

                # 写入寄存器值1到地址0x0000      0放料或取料的动作命令  1取料 2放料
                addr = 0x0000  # 寄存器地址
                value_to_write = 2
                result = c.write_single_register(addr, value_to_write)
                item.status="FullNG"
                #removed_material = NGHouse.pop(0).name  # 移除仓库第一个原料位置
                robotic_arm.work = "Working"
                return f"放料完成，已放置到：{item.name}"
            #else:
        for item in OKHouse:
            if item.status == "empty" :
                addr4 = 0x0004  # 寄存器地址
                value_to_write4 = 0x0000  # 0x4409#0x43ca,0x8000,0x42be,0x0000
                result4 = c.write_single_register(addr4, value_to_write4)

                addr5 = 0x0005  # 寄存器地址
                value_to_write5 = 0x0000  # 0x8000
                result5 = c.write_single_register(addr5, value_to_write5)

                addr8 = 0x0008  # 寄存器地址
                value_to_write8 = 0x0000  # 0x433e
                result8 = c.write_single_register(addr8, value_to_write8)

                addr9 = 0x0009  # 寄存器地址
                value_to_write9 = 0x0000  # 0x0000
                result9 = c.write_single_register(addr9, value_to_write9)

                addr2 = 0x0002  # 寄存器地址
                value_to_write2 = item.x1  # 0x4409
                result2 = c.write_single_register(addr2, value_to_write2)

                addr3 = 0x0003  # 寄存器地址
                value_to_write3 = item.x2  # 0x8000
                result3 = c.write_single_register(addr3, value_to_write3)

                addr6 = 0x0006  # 寄存器地址
                value_to_write6 = item.y1  # 0x433e
                result6 = c.write_single_register(addr6, value_to_write6)

                addr7 = 0x0007  # 寄存器地址
                value_to_write7 = item.y2  # 0x0000
                result7 = c.write_single_register(addr7, value_to_write7)


                addr = 0x0000
                value_to_write = 2
                result = c.write_single_register(addr, value_to_write)



                item.status="FullNG"
                #removed_material = OKHouse.pop(0)  # 移除仓库第一个原料位置
                robotic_arm.work = "Working"
                return f"NG库已满，放料完成，已暂时放置到：{item.name}"
            #else:
        return "成品库已满"


def getHouseStatus(shuru):
    iswork = robotic_arm.work
    if iswork == "Working" :
        work = shuru
    else :
        work = ""
    item1 = wareHouse[0]
    item1_name = item1.name
    item1_status = item1.status

    item2 = wareHouse[1]
    item2_name = item2.name
    item2_status = item2.status

    item3 = NGHouse[0]
    item3_name = item3.name
    item3_status = item3.status

    item4 = OKHouse[0]
    item4_name = item4.name
    item4_status = item4.status

    # 是否工作、取料/放料、库名字、库状态
    return iswork, work, item1_name, item1_status, item2_name, item2_status, item3_name, item3_status, item4_name, item4_status

# 假设仓库中的原料库
# 创建wareItem对象并加入列表
# wareHouse = [wareItem(0x43ca, 0x8000, 0x43a6, 0x8000, "have", "原料1"), wareItem(0x43ca, 0x8000, 0x4382, 0x0000, "have", "原料2"), wareItem(0x43ca, 0x8000, 0x433e, 0x0000, "have", "原料3"),
#         wareItem(0x4409,0x8000,0x43a6,0x8000, "have", "原料4"), wareItem(0x4409,0x8000,0x4382,0x0000, "have", "原料5"), wareItem(0x4409,0x8000,0x433e,0x0000, "have", "原料6"),
#         wareItem(0x442d,0xc000,0x43aa,0x0000, "have", "原料7"), wareItem(0x442d,0xc000,0x4387,0x0000, "have", "原料8"), wareItem(0x442d,0xc000,0x4348,0x0000, "have", "原料9")]

#成品库分为NG库和OK库
# NGHouse = [NGItem(0x442d,0xc000,0x42be,0x0000, "empty", "NG1"), NGItem(0x442d,0xc000,0x41c8,0x0000, "empty", "NG2"), NGItem(0x442d,0xc000,0xc234,0x0000, "empty", "NG3")]#NGHouse = ["NG1","NG2","NG3"]
#
# OKHouse = [OKItem(0x43ca,0x8000,0x42be,0x0000, "empty", "OK1"), OKItem(0x43ca,0x8000,0x41c8,0x0000, "empty", "OK2"), OKItem(0x43ca,0x8000,0xc234,0x0000, "empty", "OK3"),
#            OKItem(0x4409,0x8000,0x42be,0x0000, "empty", "OK4"), OKItem(0x4409,0x8000,0x41c8,0x0000, "empty", "OK5"), OKItem(0x4409,0x8000,0xc234,0x0000, "empty", "OK6")]

# 假设仓库中的原料库
# 创建wareItem对象并加入列表
# wareHouse = [wareItem(0x43db, 0x0000, 0x4387, 0x0000, "have", "原料1"), wareItem(0x4420, 0x0000, 0x4387, 0x0000, "have", "原料2")]
#
# #成品库分为NG库和OK库
# NGHouse = [NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1")]
#
# OKHouse = [OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1")]

# 假设仓库中的原料库
# 创建wareItem对象并加入列表
wareHouse = [wareItem(0x43db, 0x0000, 0x4385, 0x8000, "have", "原料1"), wareItem(0x441f, 0x8000, 0x4384, 0x8000, "have", "原料2"),wareItem(0x43db, 0x0000, 0x4385, 0x8000, "have", "原料3"), wareItem(0x441f, 0x8000, 0x4384, 0x8000, "have", "原料4"),wareItem(0x43db, 0x0000, 0x4385, 0x8000, "have", "原料5")]

#成品库分为NG库和OK库
NGHouse = [NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1"),NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1"),NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1"),NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1"),NGItem(0x43db,0x0000,0x4220,0x0000, "empty", "NG1")]#NGHouse = ["NG1"]

OKHouse = [OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1"),OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1"),OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1"),OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1"),OKItem(0x4420,0x0000,0x4220,0x0000, "empty", "OK1")]

robotic_arm = RoboticArm("Not Work")



# 产线验收接口
def PInput(user_input):
    if user_input == "取料":
        print(c.read_holding_registers(0x0001, 1)[0])
        result = getMaterial(user_input)  # 调用函数进行处理

        print(c.read_holding_registers(0x0001, 1)[0])
        return result# 输出处理结果
    elif user_input == "放料OK":
        result = putMaterial(user_input)  # 调用函数进行处理
        return result# 输出处理结果
    elif user_input == "放料NG":
        result = putMaterial(user_input)  # 调用函数进行处理
        return result# 输出处理结果
    else:

        return result# 输出处理结果

    # 关闭连接
    c.close()

# 3D大屏接口
def PInput3D(user_input):
    if user_input == "取料":
        getMaterial(user_input)
        # 获取当前龙门的状态
        # result = getHouseStatus(user_input)
        # 返回当前龙门的状态给调用它的接口
        # getLongMenResult.get_LongMenResult(result)
        # 设置时间，过了设定的时间就对龙门的状态进行更新
        time.sleep(5)#龙门寄存器的值是否可以读取
        # 获取龙门新的状态
        robotic_arm.work = "Not Work"  #首先改变龙门机械臂的工作状态
        # result = getHouseStatus(user_input)
        # 返回龙门新的状态给调用它的接口
        # getLongMenResult.get_LongMenResult(result)
        # return result

    elif user_input == "放料OK":
        putMaterial(user_input)
        # result = getHouseStatus(user_input)

        time.sleep(5)
        robotic_arm.work = "Not Work"
        # return result

    elif user_input == "放料NG":
        putMaterial(user_input)  # 调用函数进行处理
        # result = getHouseStatus(user_input)
        time.sleep(5)
        robotic_arm.work = "Not Work"
        # return result

    else:
        return result


